#pragma once

#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/client.hpp>
#include <iostream>
#include <thread>


typedef websocketpp::client<websocketpp::config::asio> client;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
typedef websocketpp::connection_hdl connection_hdl;

// 本地客户端
class local_client
{
private:
    client c_;
    std::string uri_;
    connection_hdl hdl_;
public:
    local_client(/* args */);
    ~local_client();
    void run()
    {
        try {

            websocketpp::lib::error_code ec;
            client::connection_ptr con = c_.get_connection(uri_, ec);
            if (ec) {
                std::cout << "local_client could not create connection because: " << ec.message() << std::endl;
                return;
            }

            // Note that connect here only requests a connection. No network messages are
            // exchanged until the event loop starts running in the next line.
            c_.connect(con);

            // Start the ASIO io_service run loop
            // this will cause a single connection to be made to the server. c_.run()
            // will exit when this connection is closed.
            // 进入事件循环
            // std::this_thread::sleep_for(std::chrono::seconds(5));
            
            // c_.start_perpetual();
            // websocketpp::lib::shared_ptr<websocketpp::lib::thread> thread;
            // thread.reset(new websocketpp::lib::thread(&client::run, &c_));

            // 在另一个线程中执行 本地客户端的 run 函数
            websocketpp::lib::thread* asio_thread = new websocketpp::lib::thread(&client::run, &c_);
            
            // 睡眠1秒 给本地客户端连接本地服务器 以充足的时间
            std::this_thread::sleep_for(std::chrono::seconds(1));

            //std::cout << "local_client::run 执行完毕" << std::endl;
            
        } catch (websocketpp::exception const & e) {
            std::cout << "local_client 抛出异常: " << e.what() << std::endl;
        }
        
    }

    void on_open(connection_hdl hdl) 
    {
        hdl_ = hdl;
        //std::cout << "local_client connected to server!!!" << std::endl;
        //std::cout << "thread   " << std::this_thread::get_id() << std::endl;
    }

    void ping()
    {
        //std::cout << "真的准备ping了" << std::endl;
        c_.ping(hdl_, "flush_send_queue");
        //std::cout << "真的ping完成了" << std::endl;
        //std::cout << "调用真正 ping 的线程：" << std::this_thread::get_id() << std::endl;
    }
};

local_client::local_client(/* args */)
{
    std::cout << "本地客户端构造......" << std::endl;
    uri_ = "ws://127.0.0.1:8083";
    // 清除日志输出
    c_.clear_access_channels(websocketpp::log::alevel::all);
    c_.set_error_channels(websocketpp::log::elevel::none);
    // 设置连接事件回调函数
    c_.set_open_handler(std::bind(&local_client::on_open, this, std::placeholders::_1));
    // Initialize ASIO
    c_.init_asio();
}

local_client::~local_client()
{

}
